﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using System.Reflection;
using System.Collections;
using WS.EKA.Model;

namespace WS.EKA.Service.Test
{
    public class ObjectComparer<T> : IEqualityComparer<T>
    {
        private readonly static ObjectComparer<T> instance=new ObjectComparer<T>();
       
        public static IEqualityComparer<T> CreateInsance()
        {
            return instance as IEqualityComparer<T>;
        }

        public bool ValueEqual( object actual, object expected)
        {
            PropertyInfo[] properties = expected.GetType().GetProperties();
            foreach (PropertyInfo property in properties)
            {
                object expectedValue = property.GetValue(expected, null);
                object actualValue = property.GetValue(actual, null);

                if (actualValue is IList)
                {
                    if (!AssertListsAreEquals(property, (IList)actualValue, (IList)expectedValue))
                        return false;
                }
                else if (actualValue is DateTime)
                {
                    if (!Equals(expectedValue.ToString(), actualValue.ToString()))
                        return false;
                }
                else if (actualValue is BaseModel)
                {
                    if (!ValueEqual(actualValue, expectedValue))
                        return false;
                }
                else
                {
                    if (!Equals(expectedValue, actualValue))
                        return false;
                }
            }
            return true;
        }

        private bool AssertListsAreEquals(PropertyInfo property, IList actualList, IList expectedList)
        {
            if (actualList.Count != expectedList.Count)
                return false;

            for (int i = 0; i < actualList.Count; i++)
            {
                if (!Equals(actualList[i], expectedList[i]))
                    return false;
            }
            return true;
        }

        public bool Equals(T x, T y)
        {
            return ValueEqual(x, y);
        }

        public int GetHashCode(T obj)
        {
            return obj.GetHashCode();
        }
    }

}
